﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CrankShaftAnalysisSystem.Devices
{
    public class LinearLC485
    {
        private static readonly LinearLC485 instance = new LinearLC485();

        /// <summary>
        /// 显式的静态构造函数用来告诉C#编译器在其内容实例化之前不要标记其类型
        /// 静态构造函数是C#的一个新特性，其实好像很少用到。 
        /// 不过当我们想初始化一些静态变量的时候就需要用到它了。 这个构造函数是属于类的，
        /// 而不是属于哪里实例的，就是说这个构造函数只会被执行一次。 
        /// 也就是在创建第一个实例或引用任何静态成员之前，由.NET自动调用
        /// </summary>
        static LinearLC485() { }

        private LinearLC485()
        {
            Index = 1;  // 传感器插在X2的位置
        }

        public static LinearLC485 Instance
        {
            get
            {
                return instance;
            }
        }

        public ushort Index { get; set; }
        public bool Initialised { get; private set; } = false;
        public bool Warning { get; private set; } = false;
        public double Height { get; private set; }

        public ushort endat_status = 0;
        public short endat_read_status = 0;
        public ushort device_type = 0;
        public ushort endat_alarm = 0;
        public uint endat_signal_period = 0;

        public bool Init()
        {
            return IK220.IK220Init(Index);
        }

        public bool Begin()
        {
            bool ret = true;
            ret &= IK220.IK220Init(Index);
            ret &= IK220.IK220WritePar(Index, 1, 1);
            ret &= IK220.IK220WritePar(Index, 2, 1);
            /* pStatus: Pointer to a variable in which the EnDat status is saved.
             0 = OK
             1 = Encoder does not answer or is not connected
             2 = Transmission error
             3 = Error mode echo
             4 = Error CRC sum
             5 = Error data echo
             6 = Error MRS code / address echo */
            ret &= IK220.IK220ResetEn(Index, out endat_status);
            ret &= IK220.IK220ConfigEn(Index, out endat_status, out device_type, out endat_signal_period, out _, out _, out _, out _);
            Initialised = ret;
            return ret;
        }

        /// <summary>
        /// Get Absolute Distance
        /// </summary>
        /// <returns> Absolute Disdance at um </returns>
        public double ReadLinearDis()
        {
            double PulseOutput;
            IK220.IK220ReadEn(Index, out endat_read_status, out PulseOutput, out endat_alarm);
            Warning = endat_alarm > 0;
            Height = PulseOutput * endat_signal_period / 1000.0;
            return Height;
        }
    }
}
